package com.irdstudio.apicenter.frame.service;

import java.io.File;
import java.io.IOException;

import org.dom4j.DocumentException;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNStatus;

import com.irdstudio.apicenter.console.util.MacmsPathUtil;
import com.irdstudio.apicenter.core.dvo.RspValue;
import com.irdstudio.apicenter.frame.util.SVNUtil;

/**
 * Svn服务组件(提供针对Svn的各种操作)
 * 
 * @author zs.ligm
 * @version 1.0
 * @date 2015-07-30
 */
public class SvnProjectService extends AbstractService {

	/* Svn服务器地址,属性通过BEAN注入 */
	private String serverUrl;

	/* Svn用户ID,属性通过BEAN注入 */
	private String svnUserId;

	/* Svn用户密码,属性通过BEAN注入 */
	private String svnPasswd;

	@Override
	public String getName() {
		return "SvnProjectService";
	}

	@Override
	public void start() {
		logger.info("Svn服务器地址:" + this.getServerUrl());
		logger.info("    Svn用户名:" + this.getSvnUserId());
		logger.info("  Svn用户密码:" + this.getSvnPasswd());
		logger.info("验证Svn库...");
		SVNClientManager svnClientManager = SVNUtil.authSvn(
				this.getServerUrl(), this.getSvnUserId(), this.getSvnPasswd());
		if (svnClientManager != null) {
			logger.info("Svn库验证成功...");
		} else {
			logger.info("Svn库验证失败...");
		}
		// this.updateProject("1000");
	}

	/**
	 * 导出指定工程到指定目录
	 * 
	 * @param projectName
	 * @return
	 */
	public boolean exportProject(String projectName, String exportDirectory) {
		
		String projectSvnUrl = getProjectSvnUrl(projectName);
		// 进行一次授权验证
		SVNClientManager clientManager = SVNUtil.authSvn(projectSvnUrl, this
				.getSvnUserId(), this.getSvnPasswd());

		// 要导出的SVN工程地址
		SVNURL url = SVNUtil.makeSVNURL(projectSvnUrl);
		if (url == null)
			return false;

		// 要导出工程到本地的目标路径
		File destPath = new File(exportDirectory);
		return SVNUtil.doExport(clientManager, url, destPath) > 0;
	}

	/**
	 * 从SVN中检出工程副本
	 * 
	 * @param projectName
	 * @return
	 */
	public boolean checkoutProject(String projectName) {

		String projectSvnUrl = getProjectSvnUrl(projectName);

		// 进行一次授权验证
		SVNClientManager clientManager = SVNUtil.authSvn(projectSvnUrl, this
				.getSvnUserId(), this.getSvnPasswd());

		// 要checkout的SVN工程地址
		SVNURL url = SVNUtil.makeSVNURL(projectSvnUrl);
		if (url == null)
			return false;

		// 要checkou工程到本地的目标路径
		File destPath = new File(MacmsPathUtil.getMacmsAppPrjPath(projectName));
		SVNUtil.checkout(clientManager, url, SVNRevision.HEAD, destPath,
				SVNDepth.INFINITY);
		return false;
	}

	/**
	 * 从Svn库中更新工程
	 * 
	 * @param projectName
	 * @return
	 */
	public boolean updateProject(String projectName) {
		String projectSvnUrl = getProjectSvnUrl(projectName);

		// 进行一次授权验证
		SVNClientManager clientManager = SVNUtil.authSvn(projectSvnUrl, this
				.getSvnUserId(), this.getSvnPasswd());

		// 要checkout的SVN工程地址
		SVNURL url = SVNUtil.makeSVNURL(projectSvnUrl);
		if (url == null)
			return false;

		// 要update工程到本地的目标路径
		File destPath = new File(MacmsPathUtil.getMacmsAppPrjPath(projectName));
		SVNUtil.update(clientManager, destPath, SVNRevision.HEAD,
				SVNDepth.INFINITY);
		return false;
	}

	/**
	 * 增加一个工程到Svn库中
	 * 
	 * @param projectName
	 * @return
	 */
	public RspValue addProject(String projectName) {

		String projectSvnUrl = getProjectSvnUrl(projectName);
		SVNClientManager clientManager = SVNUtil.authSvn(projectSvnUrl, this
				.getSvnUserId(), this.getSvnPasswd());

		// 应用工程要提交到的Svn地址
		SVNURL destUrl = SVNUtil.makeSVNURL(projectSvnUrl);
		if (destUrl == null)
			return new RspValue("解释svn地址失败!");

		// 判断工程是否已经存在
		if (SVNUtil.isURLExist(destUrl, this.getSvnUserId(), this
				.getSvnPasswd())) {
			return new RspValue("工程已经存在!");
		}

		// 应用工程目录
		File destPath = new File(MacmsPathUtil.getMacmsAppPrjPath(projectName));

		// 导入工程目录到SVN中
		if (SVNUtil.importDirectory(clientManager, destPath, destUrl,
				"复制基础工程到应用工程并导入!", true) != null) {
			return new RspValue();
		} else {
			return new RspValue("导入工程到SVN失败!");
		}
	}

	/**
	 * 从Svn库的工程中更新指定文件
	 * 
	 * @param projectName
	 * @param fileName
	 * @return
	 */
	public boolean updateProjectFile(String projectName, String fileName) {
		// TODO:待实现
		return false;
	}

	/**
	 * 提交指定工程下的文件到Svn库中
	 * 
	 * @param projectName
	 * @param fileName
	 * @return
	 */
	public boolean commitProjectFile(String projectName, File[] wcPath) {
		String projectSvnUrl = getProjectSvnUrl(projectName);
		// 进行一次授权验证
		SVNClientManager clientManager = SVNUtil.authSvn(projectSvnUrl, this
				.getSvnUserId(), this.getSvnPasswd());
		// 要checkout的SVN工程地址
		/*SVNURL url = SVNUtil.makeSVNURL(projectSvnUrl);
		if (url == null)
			return false;*/
		SVNUtil.commitCombination(clientManager, wcPath, true, "提交指定工程下的文件到Svn库中");
		return true;
	}

	/**
	 * 修改项目文件
	 * 
	 * @param project
	 * @throws DocumentException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	private void editProjectFile(String projectName) {

		String projectPath = MacmsPathUtil.getMacmsAppPrjPath(projectName);

		// String settings = projectPath + ".settings/";
		//
		// // 1. 修改.settings/org.eclipse.wst.common.component
		// Document document = null;
		// try {
		// document = XmlReaderUtil.getDocument(new File(settings
		// + "org.eclipse.wst.common.component"));
		// } catch (DocumentException e) {
		// e.printStackTrace();
		// }
		//
		// Element root = document.getRootElement();
		//
		// root.element("wb-module").attribute("deploy-name").setValue(
		// project.getName());
		//
		// if (root.element("wb-module").element("property").attribute("name")
		// .getValue().equals("java-output-path")) {
		//
		// root.element("wb-module").element("property").attribute("value")
		// .setValue("/" + project.getName() + "/build/classes");
		// }
		//
		// Iterator<Element> itr = (Iterator<Element>)
		// XmlReaderUtil.getElements(
		// document, "//wb-module//property").iterator();
		//
		// while (itr.hasNext()) {
		// Element element = itr.next();
		// if ("context-root".equals(element.attribute("name").getValue())) {
		// element.attribute("value").setValue("/" + project.getName());
		// }
		// }
		//
		// // 将修改后的值写入
		// XmlReaderUtil.writerXml(document, settings
		// + "org.eclipse.wst.common.component");
		//
		// // 2. 修改.project
		// try {
		// document = XmlReaderUtil.getDocument(new File(pro + ".project"));
		// XmlReaderUtil.setElementText(document, "//projectDescription",
		// "name", project.getName());
		// XmlReaderUtil.writerXml(document, pro + ".project");
		// } catch (DocumentException e) {
		// e.printStackTrace();
		// }
	}

	/**
	 * 根据工程名返回其Svn地址
	 * 
	 * @param projectName
	 * @return
	 */
	public String getProjectSvnUrl(String projectName) {
		if (serverUrl.endsWith("/")) {
			return serverUrl + projectName;
		} else {
			return serverUrl + "/" + projectName;
		}
	}
	
	/**
	 * 在存储库上创建一个目录
	 * 
	 * @param projectName
	 * @return
	 */
	public void createSvnDirect(String projectName, String dir) {
		String projectSvnUrl = getProjectSvnUrl(projectName);
		// 进行一次授权验证
		SVNClientManager clientManager = SVNUtil.authSvn(projectSvnUrl, this
				.getSvnUserId(), this.getSvnPasswd());
		String projectSvnDir = getProjectSvnUrl(dir);
		System.out.println("======"+projectSvnDir);
		SVNURL destDir = SVNUtil.makeSVNURL(projectSvnDir);
		// 判断工程是否已经存在
		if (!SVNUtil.isURLExist(destDir, this.getSvnUserId(), this
				.getSvnPasswd())) {
			SVNUtil.makeDirectory(clientManager, destDir, "在存储库上创建一个目录:"+projectSvnDir);
			System.out.println("在存储库上创建一个目录:"+projectSvnDir);
		}
	}
	
	/**
	 * 判断指定目录在存储库上是否存在
	 * 
	 * @param dir
	 * @return
	 */
	public boolean isExistSvnDirect(String dir) {
		String projectSvnDir = getProjectSvnUrl(dir);
		SVNURL destDir = SVNUtil.makeSVNURL(projectSvnDir);
		// 判断工程是否已经存在
		if (SVNUtil.isURLExist(destDir, this.getSvnUserId(), this
				.getSvnPasswd())) {
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 提交指定工程下的文件到Svn库中
	 * 
	 * @param projectName
	 * @param fileName
	 * @return
	 */
	public boolean commit(String projectName, File[] wcPath) {
		String projectSvnUrl = getProjectSvnUrl(projectName);
		// 进行一次授权验证
		SVNClientManager clientManager = SVNUtil.authSvn(projectSvnUrl, this
				.getSvnUserId(), this.getSvnPasswd());
		SVNUtil.commit(clientManager, wcPath, true, "直接提交新增的文件");
		return true;
	}
	
	/**
	 * 获取此文件的状态，是文件做了修改还是新添加的文件？
	 * 
	 * @param projectName
	 * @param fileName
	 * @return
	 */
	public SVNStatus getFileStatus(String projectName, File file) {
		String projectSvnUrl = getProjectSvnUrl(projectName);
		// 进行一次授权验证
		SVNClientManager clientManager = SVNUtil.authSvn(projectSvnUrl, this
				.getSvnUserId(), this.getSvnPasswd());
		return SVNUtil.showStatus(clientManager, file, true);
	}

	@Override
	public void terminate() {
		// 释放服务组件所占用的内存
	}

	public String getServerUrl() {
		return serverUrl;
	}

	public void setServerUrl(String serverUrl) {
		this.serverUrl = serverUrl;
	}

	public String getSvnUserId() {
		return svnUserId;
	}

	public void setSvnUserId(String svnUserId) {
		this.svnUserId = svnUserId;
	}

	public String getSvnPasswd() {
		return svnPasswd;
	}

	public void setSvnPasswd(String svnPasswd) {
		this.svnPasswd = svnPasswd;
	}

}
